import {PlusOutlined} from '@ant-design/icons';
import {useRequest} from 'umi';
// @ts-ignore
import {Button, Col, Divider, Form, Icon, Input, List, message, Modal, Row, Select, Space, Tag, Tree} from 'antd';
import React, {useState} from 'react';
import {PageContainer} from '@ant-design/pro-layout';
// @ts-ignore
import ProTable, {ActionType, ProColumns} from '@ant-design/pro-table';
import {DataView} from './data.d';
import {listForSelect} from '@/assets/service/baseService';
import {getDatabaseNameList} from '@/pages/report/SourceList/service';
import {DatabaseOutlined} from "@ant-design/icons/lib";
import CodeMirror from '@uiw/react-codemirror';
import 'codemirror/theme/3024-day.css';
import 'codemirror/addon/selection/active-line'
import {modulesUrl} from "@/assets/constant/modulesUrl";
import {hooksSet} from "@/assets/utils/utils";
import {executeSql} from './service';
import FormItem from "antd/es/form/FormItem";

require('codemirror/addon/hint/show-hint.css'); // 用来做代码提示
require('codemirror/addon/hint/show-hint.js'); // 用来做代码提示
require('codemirror/addon/hint/sql-hint.js'); // 用来做代码提示

const TableList: React.FC<{}> = () => {

  const sourceSelectList = useRequest(() => listForSelect(modulesUrl.reportSource)).data
  const [sourceTree, setSourceTree] = useState<any[]>([])
  const [columns, setColumns] = useState<any[]>([])
  const [tableData, setTableData] = useState<any[]>([])
  /**
   * 用于保存的数据
   */
  const [saveData, setSaveData] = useState<any>({
    sql: "select * from report_source where id = $id$;",
    name: "",
    sourceId: "",
    description: "",
    variables: [{title: "查询", name: "id", type: "1"}]
  })
  /**
   * 变量弹框参数
   */
  const [variableModel, setVariableModel] = useState({
    // 是否显示
    visible: false,
    // 是否是添加
    isAdd: true,
  });
  /**
   * 变量弹框form实例
   */
  const [variableForm] = Form.useForm();

  /**
   * 执行sql线程
   */
  const executeSqlRun = useRequest(() => executeSql(saveData), {
    manual: true,
    onSuccess: (result, params) => {
      // 组装表格表头
      let columnList: any[] = []
      result.columns.forEach(function (column: any) {
        columnList.push({title: column.name, dataIndex: column.name,})
      })
      hooksSet(setColumns, columnList);
      // 组装表格数据
      hooksSet(setTableData, result.resultList);
      // @ts-ignore 关闭弹框信息
      params[0]();
    }
  }).run
  /**
   * 获取数据库列表的线程
   */
  const getSourceDbsRun = useRequest((id:string) => getDatabaseNameList({id: id}), {
    manual: true, onSuccess: (result, params) => {
      // 组装tree
      if (result && result.length > 0) {
        let sourceTree: any[] = [];
        result.forEach(function (n:any) {
          sourceTree.push({"title": n, "key": n, "icon": <DatabaseOutlined/>, "isLeaf": true})
        })
        hooksSet(setSourceTree, sourceTree)
        // @ts-ignore 第二个参数为关闭弹框的方法
        params[1]();
      }
    }
  }).run
  /**
   * 加载数据源的数据库列表
   * @param fields
   */
  const selectSource = async (value:any) => {
    // 启动线程，开始加载
    // @ts-ignore
    getSourceDbsRun(value, message.loading('正在加载'));
    hooksSet(setSaveData, {sourceId: value})
  };

  /**
   * 变量保存提交
   * @param fields
   */
  const variableFormSubmit = async () => {
    let nowVariables = saveData.variables;
    let nowVariableFormValues = variableForm.getFieldsValue();
    let isSave = true;
    // 判断是否为添加
    if (variableModel.isAdd) {
      // 如果已有相同变量名则提示
      nowVariables.forEach(function (n:any) {
        if (n.name === nowVariableFormValues.name) {
          message.destroy()
          message.error('该变量已存在');
          isSave = false;
        }
      })
    }
    if (isSave) {
      // 保存
      nowVariableFormValues.title = "查询"
      nowVariables.push(nowVariableFormValues)
      hooksSet(setSaveData, {variables: nowVariables});
      // 重置form
      variableForm.resetFields()
      hooksSet(setVariableModel, {visible:false})
    }
  };

  return (
    <PageContainer title={"数据视图添加"}>
      <Row>
        <Col span={4}>
          <Space direction={"vertical"} size={"middle"}>
            <Input placeholder="请输入名称" onChange={(e)=> hooksSet(setSaveData, {name:e.target.value})}/>
            <Input placeholder="请输入描述" onChange={(e)=> hooksSet(setSaveData, {description:e.target.value})}/>
            <Select
              showSearch
              placeholder="请选择数据源"
              optionFilterProp="label"
              options={sourceSelectList}
              style={{width: "100%"}}
              onSelect={selectSource}
            />
            <Input.Search placeholder="搜索表/字段名称"/>
            <Tree
              style={{backgroundColor: "rgb(240,242,245)"}}
              showIcon
              treeData={sourceTree}
            >
            </Tree>
          </Space>
        </Col>
        <Divider type="vertical"/>
        <Col span={19}>
          <Row style={{height: "200px"}}>
            <Col span={18}>
              <CodeMirror
                value={saveData.sql}
                onChange={(a) => hooksSet(setSaveData, {sql: a.getValue()})}
                options={{
                  theme: 'monokai',
                  mode: "text/x-mysql",
                  styleActiveLine: true
                }}
              />
            </Col>
            <Divider type="vertical"/>
            <Col span={5}>
              <div style={{height: "200px", overflow: "auto"}}>
                <div style={{fontWeight: "bold"}}>
                  <span>变量</span>
                  <div style={{float: "right"}}>
                    <Button type="text" onClick={() => hooksSet(setVariableModel, {visible:true})}><PlusOutlined/></Button>
                  </div>
                </div>
                <List
                  size="small"
                  dataSource={saveData.variables}
                  renderItem={(item: any) =>
                    <List.Item onClick={() => {
                      // 初始化form
                      saveData.variables.forEach(function (n: any) {
                        if (n.name === item.name) {
                          variableForm.setFieldsValue(item)
                        }
                      })
                      hooksSet(setVariableModel, {visible:true})
                    }} style={{cursor: "pointer"}}>
                      <List.Item.Meta
                        title={<span><Tag color="green">{item.title}</Tag>{item.name}</span>}
                      />
                    </List.Item>
                  }
                />
              </div>
            </Col>
          </Row>
          <Divider/>
          <div style={{padding: "20px", backgroundColor: "white"}}>
            <ProTable<DataView>
              columns={columns}
              rowKey="key"
              pagination={{
                showQuickJumper: true,
              }}
              search={false}
              dateFormatter="string"
              options={false}
              dataSource={tableData}
              scroll={{x: true}}
              toolBarRender={false}
            />
          </div>
          <Divider/>
          <Row>
            <Col span={19}/>
            <Col span={5}>
              <Space>
                <Button>
                  取消
                </Button>
                <Button type="primary" onClick={() => {
                  // @ts-ignore
                  executeSqlRun(message.loading('正在执行'))
                }}>执行</Button>
                <Button>
                  保存
                </Button>
              </Space>
            </Col>
          </Row>
        </Col>
      </Row>
      <Modal
        title={(variableModel.isAdd ? "添加" : "编辑") + "变量"}
        visible={variableModel.visible}
        onCancel={() => hooksSet(setVariableModel, {visible:false})}
        onOk={variableFormSubmit}
        destroyOnClose
      >
        <Form form={variableForm}>
          <FormItem label="名称" name="name">
            <Input placeholder="名称"/>
          </FormItem>
          <FormItem label="类型" name="type" initialValue="string">
            <Select placeholder="类型" style={{width: "100%"}} defaultValue={"string"}>
              <Select.Option value="1">字符串</Select.Option>
              <Select.Option value="2">数字</Select.Option>
            </Select>
          </FormItem>
        </Form>
      </Modal>
    </PageContainer>
  );
};

export default TableList;
